from typing import Any, Dict, Optional, Union, List

from sqlalchemy.orm import Session

from app.crud.base import CRUDBase
from app.models.api_config import SysApiConfig
from app.schemas.api_config import ApiConfigCreate, ApiConfigUpdate


class CRUDApiConfig(CRUDBase[SysApiConfig, ApiConfigCreate, ApiConfigUpdate]):
    """
    API配置CRUD操作
    """
    def get_by_code(self, db: Session, *, code: str) -> Optional[SysApiConfig]:
        """
        根据唯一代码获取API配置
        """
        return db.query(SysApiConfig).filter(SysApiConfig.code == code).first()
    
    def create(self, db: Session, *, obj_in: ApiConfigCreate, created_by: str = None) -> SysApiConfig:
        """
        创建API配置
        """
        # 检查code是否重复
        exist_item = self.get_by_code(db, code=obj_in.code)
        if exist_item:
            raise ValueError(f"代码 '{obj_in.code}' 已存在")
        
        return super().create(db, obj_in=obj_in, created_by=created_by)
    
    def update(
        self, db: Session, *, db_obj: SysApiConfig, obj_in: Union[ApiConfigUpdate, Dict[str, Any]], updated_by: str = None
    ) -> SysApiConfig:
        """
        更新API配置
        """
        if isinstance(obj_in, dict):
            update_data = obj_in
        else:
            update_data = obj_in.dict(exclude_unset=True)
        
        # 如果要更改code，检查是否与其他记录冲突
        if "code" in update_data and update_data["code"] != db_obj.code:
            exist_item = self.get_by_code(db, code=update_data["code"])
            if exist_item:
                raise ValueError(f"代码 '{update_data['code']}' 已存在")
        
        return super().update(db, db_obj=db_obj, obj_in=obj_in, updated_by=updated_by)

    def get_multi(
        self, db: Session, *, skip: int = 0, limit: int = 100, 
        code: Optional[str] = None, name: Optional[str] = None,
        status: Optional[int] = None, api_url: Optional[str] = None
    ) -> List[SysApiConfig]:
        """
        获取多条记录，支持搜索条件
        """
        query = self._filter_query(
            db,
            code=code,
            name=name,
            status=status,
            api_url=api_url
        )
        return query.offset(skip).limit(limit).all()
        
    def _filter_query(
        self,
        db: Session,
        *,
        code: Optional[str] = None,
        name: Optional[str] = None,
        status: Optional[int] = None,
        api_url: Optional[str] = None
    ):
        query = db.query(SysApiConfig)
        if code:
            query = query.filter(SysApiConfig.code.like(f"%{code}%"))
        if name:
            query = query.filter(SysApiConfig.name.like(f"%{name}%"))
        if status is not None:
            query = query.filter(SysApiConfig.status == status)
        if api_url:
            query = query.filter(SysApiConfig.api_url.like(f"%{api_url}%"))
        return query

    def count(
        self,
        db: Session,
        *,
        code: Optional[str] = None,
        name: Optional[str] = None,
        status: Optional[int] = None,
        api_url: Optional[str] = None
    ) -> int:
        query = self._filter_query(
            db,
            code=code,
            name=name,
            status=status,
            api_url=api_url
        )
        return query.count()


# 创建实例以便导入
api_config = CRUDApiConfig(SysApiConfig)